﻿using Newtonsoft.Json;
using Programming.DemoProject.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Programming.DemoProject.AOP
{
    /// <summary>
    /// 利用 .NetRemoting动态代理
    /// .NET Core已经没有了，可以用DispatchProxy代替
    /// 
    /// 通过动态代理，完成通用功能的扩展
    /// 有了这个之后，AOP是不是就可以实现了！
    /// </summary>
    public class DynamicProxy
    {
        public static void Show()
        {
            UserInfo userInfo = new UserInfo()
            {
                Account = "Administrator",
                Name = "清光",
                Password = "888888"
            };
            {
                IDBHelper dBHelper = new MySQLDBHelper();
                dBHelper.Save(userInfo);
            }
            {
                IDBHelper dbHelper = new MySQLDBHelper();
                dbHelper = TransparentProxy.Create<IDBHelper>(dbHelper);
                dbHelper.Save(userInfo);
            }
        }
    }

    /// <summary>
    /// 真实代理
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MyRealProxy<T> : DispatchProxy
    {
        public T _Instance = default(T);

        //不同的类 不同的方法  增加不同的扩展----类/方法 上面加特性，这里检测特性
        protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
        {

            //System.Reflection.Emit

            //IP检测---HttpContext---权限检测  
            BeforeProceede(targetMethod);//Log  try-catch

            Console.WriteLine($"This is {targetMethod?.Name}-Invoked");

            if (args != null & args.Length > 0)
                Console.WriteLine($"参数信息：{JsonConvert.SerializeObject(args)}");

            var result = targetMethod?.Invoke(this._Instance, args);
            Console.WriteLine("方法自身被调用");

            //日志---性能统计---缓存一下--事务/异常处理
            AfterProceede(targetMethod);

            return result;
        }

        public void BeforeProceede(MethodInfo? targetMethod)
        {
            Console.WriteLine("方法执行前可以加入的逻辑");
        }
        public void AfterProceede(MethodInfo? targetMethod)
        {
            Console.WriteLine("方法执行后可以加入的逻辑");
        }
    }

    /// <summary>
    /// 透明代理
    /// </summary>
    public static class TransparentProxy
    {
        public static T Create<T>(T t)
        {
            dynamic tProxy = DispatchProxy.Create<T, MyRealProxy<T>>()!;
            tProxy!._Instance = t;

            return tProxy;
        }
    }
}
